package com.gtx.common.util.uuid;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @Description 加密解密工具类
 */
public class CryptoUtils {
    private static final String STR_AZ = "USws6G2WIxBDrEcC3HluKM4JYAp015Xzt7qNPFOnTma&amp;VoiyZkv9h_%jb=Lg8fdeRQ";

    private static final String publicKeyStr = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKTqQmCTzYy5TaleCiURmy2LnNTfxZz2APY9fztWeurnLPlsoatB2yZp5hg9i1vWjWlf3x+RkSpT28LIzvfhHvECAwEAAQ==";
    /**
     * @Description DES加密字符串
     * @Author smh
     * @Date 2021-06-04
     * @Modifier smh
     * @ModifyDate 2021-06-04
     * @Param password: 加密密码，长度不能够小于8位
     * @Param data: 待加密字符串
     * @Return: java.lang.String
    **/
    public static String DESEncrypt(String password, String data) throws RuntimeException {
        try {
            if (password == null || password.length() < 8) {
                throw new RuntimeException("加密失败，key不能小于8位");
            }
            Key secretKey = generateKey(password);
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(password.getBytes("UTF-8"));
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
            byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));

            //JDK1.8及以上可直接使用Base64，JDK1.7及以下可以使用BASE64Encoder
            return new String(Base64.getEncoder().encode(bytes), "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException("参数加密失败, " + e.getMessage());
        }
    }

    /**
     * @Description DES解密字符串
     * @Author smh
     * @Date 2021-06-04
     * @Modifier smh
     * @ModifyDate 2021-06-04
     * @Param password: 解密密码，长度不能够小于8位
     * @Param data: 待解密字符串
     * @Return: java.lang.String
    **/
    public static String DESDecrypt(String password, String data) {
        try {
            Key secretKey = generateKey(password);
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(password.getBytes("UTF-8"));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
            return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes("UTF-8"))), "UTF-8");
        } catch(Exception e) {
            throw new RuntimeException("参数解密失败, " + e.getMessage());
        }
    }

    /**
     * @Description 生成Key
     * @Author smh
     * @Date 2021-06-04
     * @Modifier smh
     * @ModifyDate 2021-06-04
     * @Param password:
     * @Return: java.security.Key
    **/
    private static  Key generateKey(String password) throws Exception {
        DESKeySpec dks = new DESKeySpec(password.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        return keyFactory.generateSecret(dks);
    }

    /**
     * 移位加密
     * @param s
     * @param length
     * @return
     */
    public static String moveEncrypt(String s, int length)
    {
        char[] str = s.toCharArray();

        String ss = "";
        for (int i = 0; i < str.length; i++)
        {
            char tempi = str[i];
            for (int j = 0; j < STR_AZ.toCharArray().length; j++)
            {
                //大于最大位后，从初的A取。形成循环
                if (tempi == STR_AZ.toCharArray()[j])
                {
                    if ((j + length) >= STR_AZ.toCharArray().length)
                    {
                        int z = j + length - STR_AZ.toCharArray().length;
                        ss += STR_AZ.toCharArray()[z];
                        break;
                    }
                    else
                    {
                        ss += STR_AZ.toCharArray()[j + length];
                        break;
                    }
                }
            }
        }
        return ss;
    }

    public static String encryptByPublicKey(String data)throws Exception{
        //取公钥
        byte[] keyBytes =  Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        //对数据解密
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] resultBytes=cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(resultBytes);
    }
}
